#include "StdAfx.h"
#include "SgSphere.h"

const double GR_PI = 3.1415926535897932384626433832795;

inline void Normalize(GLdouble *v)
{
    GLdouble len = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
    v[0] /= len;
    v[1] /= len;
    v[2] /= len;
}

CSgSphere::CSgSphere(double p_radius, bool p_port)
{
	m_portion = p_port;
	Sphere(p_radius);
	
}
CSgSphere::CSgSphere(double p_radius)
{
	m_portion = false;
	Sphere(p_radius);
	
}

CSgSphere::~CSgSphere(void)
{
}

void CSgSphere::Sphere(double p_radius)
{


    GLdouble a[] = {1, 0, 0};
    GLdouble b[] = {0, 0, -1};
    GLdouble c[] = {-1, 0, 0};
    GLdouble d[] = {0, 0, 1};
    GLdouble e[] = {0, 1, 0};
    GLdouble f[] = {0, -1, 0};

	/*glEnable(GL_TEXTURE_2D);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    glBindTexture(GL_TEXTURE_2D, m_worldmap.TexName());*/

    int recurse = 5;

	if (!m_portion)
	{
    SphereFace(recurse, p_radius, d, a, e);
    SphereFace(recurse, p_radius, a, b, e);
    SphereFace(recurse, p_radius, b, c, e);
    SphereFace(recurse, p_radius, c, d, e);
    SphereFace(recurse, p_radius, a, d, f);
    SphereFace(recurse, p_radius, b, a, f);
	}
    SphereFace(recurse, p_radius, c, b, f);
    SphereFace(recurse, p_radius, d, c, f);

	//glDisable(GL_TEXTURE_2D);
}


//
// Name :         CChildView::SphereFace()
// Description :  Draw a single facet of the sphere.  If p_recurse > 1,
//                triangulate that facet and recurse.
//

void CSgSphere::SphereFace(int p_recurse, double p_radius, GLdouble *a, GLdouble *b, GLdouble *c)
{
    if(p_recurse > 1)
    {
        // Compute vectors halfway between the passed vectors
        GLdouble d[3] = {a[0] + b[0], a[1] + b[1], a[2] + b[2]};
        GLdouble e[3] = {b[0] + c[0], b[1] + c[1], b[2] + c[2]};
        GLdouble f[3] = {c[0] + a[0], c[1] + a[1], c[2] + a[2]};

        Normalize(d);
        Normalize(e);
        Normalize(f);

        SphereFace(p_recurse-1, p_radius, a, d, f);
        SphereFace(p_recurse-1, p_radius, d, b, e);
        SphereFace(p_recurse-1, p_radius, f, e, c);
        SphereFace(p_recurse-1, p_radius, f, d, e);
    }

	CSgPtr<CSgPolygon> f1 = new CSgPolygon(); 
	// What's the texture coordinate for this normal?
    GLdouble tx1 = atan2(a[0], a[2]) / (2. * GR_PI) + 0.5;
    GLdouble ty1 = asin(a[1]) / GR_PI + .5;

    f1->AddTexCoord( CGrVector(tx1,ty1,0) );
	f1->AddNormal(a);
   
	f1->AddVertex3dv( CGrVector(a[0] * p_radius, a[1] * p_radius, a[2] * p_radius) );
	

	// The second vertex
    GLdouble tx = atan2(b[0], b[2]) / (2. * GR_PI) + 0.5;
    GLdouble ty = asin(b[1]) / GR_PI + .5;
    if(tx < 0.75 && tx1 > 0.75)
    tx += 1.0;
    else if(tx > 0.75 && tx1 < 0.75)
    tx -= 1.0;

	f1->AddTexCoord( CGrVector(tx,ty,0) ); 
	f1->AddNormal(b);
	f1->AddVertex3dv( CGrVector(b[0] * p_radius, b[1] * p_radius, b[2] * p_radius ) );
	
	// The third vertex
    GLdouble tx3 = atan2(c[0], c[2]) / (2. * GR_PI) + 0.5;
    GLdouble ty3 = asin(c[1]) / GR_PI + .5;
    if(tx3 < 0.75 && tx1 > 0.75)// && tx <.75)
    tx3 += 1.0;
    else if(tx3 > 0.75 && tx1 < 0.75)// && tx >.75)
    tx3 -= 1.0;

	f1->AddTexCoord( CGrVector(tx3,ty3,0) ); 
    f1->AddNormal(c);
    f1->AddVertex3dv( CGrVector(c[0] * p_radius, c[1] * p_radius, c[2] * p_radius) );
	m_sphereFaces.push_back(f1);
    
}

void CSgSphere::Render()
{
	std::vector< CSgPtr<CSgPolygon> >::iterator n=m_sphereFaces.begin();
	for(std::vector< CSgPtr<CSgPolygon> >::iterator i = m_sphereFaces.begin(); i!=m_sphereFaces.end(); i++)
	{	
		(*i)->Render();
        
	}
}

